package com.csj.DesignPattern.visitor;

public class Dispatch {
    public static void main(String[] args) {
        //编译时期只知道对象的静态类型（即Animal1），而运行的时候是调用的对象的真实类型（Dog1）
        Animal1 animal1 = new Animal1();
        Animal1 dog1 = new Dog1();
        animal1.eat();
        dog1.eat();

        System.out.println("===============");

        //由于animal2和dog2都是Animal2类型的
        Animal2 animal2 = new Animal2();
        Animal2 dog2 = new Dog2();
        Execute2 exe = new Execute2();
        //所以在调用方法时，就会选择execute(Animal2 a)这个方法
        //这是在编译时期就已经指定了的，jvm只被要求执行execute(Animal2 a)，即下面两个方法对于jvm来说是同一个方法
        exe.execute(animal2);
        exe.execute(dog2);

        System.out.println("===============");

        //双分派，在重载前面加上继承，使得重载也是动态的
        Animal3 animal3 = new Animal3();
        Animal3 dog3 = new Dog3();
        Execute3 execute3 = new Execute3();
        animal3.execute(execute3);
        //调用的是Animal3的子类Dog3中的方法,属于动态分派
        dog3.execute(execute3);
    }
}
//动态分派：
//指运行运行时期，动态地之置换掉某个方法。  动态分派一般通过方法的重写来实现

class Animal1 {
    public void eat()
    {
        System.out.println("Animal1");
    }
}

class Dog1 extends Animal1 {
    @Override
    public void eat() {
        System.out.println("Dog1");
    }
}

//静态分派：
//指在编译时期，就已经根绝静态类型分派完了，大白话：在编译时期就已经确定了要执行的方法     静态分派一般是根据方法的重载
class Animal2 {

}

class Dog2 extends Animal2 {

}

class Execute2 {
    public void execute(Animal2 a) {
        System.out.println("Animal2");
    }
    public void execute(Dog2 d) {
        System.out.println("Dog2");
    }
}

class Animal3 {
    public void execute(Execute3 execute) {
        //此时的this就是Dog3对象
        //属于静态分派
        execute.execute(this);
    }
}

class Dog3 extends Animal3 {
    @Override
    public void execute(Execute3 execute) {
        execute.execute(this);
    }
}

class Execute3 {
    public void execute(Animal3 a) {
        System.out.println("Animal3");
    }
    public void execute(Dog3 d) {
        System.out.println("Dog3");
    }
}